<!DOCTYPE html>
<html lang="en">
  <head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
 
<link rel="stylesheet" href="../assets/css/style.css"/> 
<!-- Copyright 1998-2021 by Northwoods Software Corporation. -->    <title> GoJS Legends and Titles -- Northwoods Software </title>
    <link rel="stylesheet" href="../assets/css/prism.css"  />
  </head>
  <script>
    
    window.diagrams = [];
    window.goCode = function(pre, w, h, parentid, animation) {
      window.diagrams.push([pre, w, h, parentid, animation]);
    }
  </script>
  <body>
  <nav id="navTop" class="w-full z-30 top-0 text-white bg-nwoods-primary">
    <div class="w-full container max-w-screen-lg mx-auto flex flex-wrap sm:flex-nowrap items-center justify-between mt-0 py-2">
      <div class="md:pl-4">
        <a class="text-white hover:text-white no-underline hover:no-underline
        font-bold text-2xl lg:text-4xl rounded-lg hover:bg-nwoods-secondary " href="../">
          <h1 class="mb-0 p-1 ">GoJS</h1>
        </a>
      </div>
      <button id="topnavButton" class="rounded-lg sm:hidden focus:outline-none focus:ring" aria-label="Navigation">
        <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
          <path id="topnavOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
          <path id="topnavClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
        </svg>
      </button>
      <div id="topnavList" class="hidden lg:text-base sm:block items-center w-auto mt-0 text-white p-0 z-20">
        <ul class="list-reset list-none font-semibold flex justify-end flex-wrap sm:flex-nowrap items-center px-0 pb-0">
          <li class="p-1 sm:p-0"><a class="topnav-link" href="../learn/">Learn</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="../samples/">Samples</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="../intro/">Intro</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="../api/">API</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/products/register.html">Register</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="../download.html">Download</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="https://forum.nwoods.com/c/gojs/11">Forum</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/contact.html"
           target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/sales/index.html"
           target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a></li>
        </ul>
      </div>
    </div>
    <hr class="border-b border-gray-600 opacity-50 my-0 py-0" />
  </nav>
    
    <div class="md:flex flex-col md:flex-row md:min-h-screen w-full max-w-screen-xl mx-auto">
      
    <div id="navSide" class="flex flex-col w-full md:w-40 lg:w-48 text-gray-700 bg-white flex-shrink-0">
      <div class="flex-shrink-0 px-8 py-4">
        <button id="navButton" class="rounded-lg md:hidden focus:outline-none focus:ring" aria-label="Navigation">
          <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
            <path id="navOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
            <path id="navClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
          </svg>
        </button>
      </div>
      <nav id="navList" class="min-h-screen hidden md:block sidebar-nav flex-grow px-1 lg:px-4 pb-4 md:pb-0 md:overflow-y-auto break-words">
  <a href="index.html">Basics</a>
  <a href="buildingObjects.html">Building Parts</a>
  <a href="usingModels.html">Using Models</a>
  <a href="dataBinding.html">Data Binding</a>
  <a href="react.html">GoJS with React</a>
  <a href="angular.html">GoJS with Angular</a>
  <a href="textBlocks.html">TextBlocks</a>
  <a href="shapes.html">Shapes</a>
  <a href="pictures.html">Pictures</a>
  <a href="panels.html">Panels</a>
  <a href="tablePanels.html">Table Panels</a>
  <a href="brush.html">Brushes</a>
  <a href="sizing.html">Sizing Objects</a>
  <a href="itemArrays.html">Item Arrays</a>
  <a href="changedEvents.html">Changed Events</a>
  <a href="transactions.html">Transactions</a>
  <a href="viewport.html">Coordinates</a>
  <a href="initialView.html">Initial View</a>
  <a href="collections.html">Collections</a>
  <a href="links.html">Links</a>
  <a href="linkLabels.html">Link Labels</a>
  <a href="connectionPoints.html">Link Points</a>
  <a href="ports.html">Ports</a>
  <a href="nodes.html">Nodes</a>
  <a href="debugging.html">Debugging</a>
  <a href="layouts.html">Layouts</a>
  <a href="trees.html">Trees</a>
  <a href="subtrees.html">SubTrees</a>
  <a href="groups.html">Groups</a>
  <a href="subgraphs.html">SubGraphs</a>
  <a href="sizedGroups.html">Sized Groups</a>
  <a href="selection.html">Selection</a>
  <a href="highlighting.html">Highlighting</a>
  <a href="animation.html">Animation</a>
  <a href="toolTips.html">ToolTips</a>
  <a href="contextmenus.html">Context Menus</a>
  <a href="events.html">Diagram Events</a>
  <a href="tools.html">Tools</a>
  <a href="commands.html">Commands</a>
  <a href="permissions.html">Permissions</a>
  <a href="validation.html">Validation</a>
  <a href="HTMLInteraction.html">HTML Interaction</a>
  <a href="layers.html">Layers &amp; Z-ordering</a>
  <a href="palette.html">Palette</a>
  <a href="overview.html">Overview</a>
  <a href="resizing.html">Resizing Diagrams</a>
  <a href="replacingDeleting.html">Replacing and Deleting</a>
  <a href="buttons.html">Buttons</a>
  <a href="templateMaps.html">Template Maps</a>
  <a href="legends.html">Legends and Titles</a>
  <a href="extensions.html">Extensions</a>
  <a href="geometry.html">Geometry Strings</a>
  <a href="grids.html">Grid Patterns</a>
  <a href="graduatedPanels.html">Graduated Panels</a>
  <a href="makingImages.html">Diagram Images</a>
  <a href="makingSVG.html">Diagram SVG</a>
  <a href="printing.html">Printing</a>
  <a href="serverSideImages.html">Server-side Images</a>
  <a href="nodeScript.html">GoJS in Node.js</a>
  <a href="testing.html">Testing</a>
  <a href="storage.html">Storage</a>
  <a href="performance.html">Performance</a>
  <a href="source.html">Building from Source</a>
  <a href="platforms.html">Platforms</a>
  <a href="deployment.html">Deployment</a>
      </nav>
    </div>      
      <div class="pt-4 px-2 md:px-0 lg:px-4 pb-16 w-full overflow-hidden">




<h1>Legends and Titles</h1>
<p>
Sometimes in addition to the nodes and links that are the subject of a diagram,
one also wants to display a "legend" or "key" describing the different kinds of nodes or links.
Perhaps one also wants there to be "title" for the diagram in large letters.
</p>

<h2 id="OutsideOfDiagram">Outside of Diagram</h2>
<p>
First, you must consider whether titles or legends should be part of the diagram or not.
You can create whatever you want in HTML outside of the diagram.
</p>
<script>
function setupForLegend(diagram) {
  var $ = go.GraphObject.make;

  diagram.layout = $(go.TreeLayout, { angle: 90 });

  diagram.nodeTemplate =
    $(go.Node, "Auto",
      $(go.Shape, "RoundedRectangle",
        { fill: "white" },
        new go.Binding("fill", "color")),
      $(go.TextBlock, { margin: 5 },
        new go.Binding("text", "key"))
    );

  diagram.linkTemplate =
    $(go.Link,
      { routing: go.Link.Orthogonal, corner: 8 },
      $(go.Shape, { strokeWidth: 2 }));

  diagram.model = new go.TreeModel([
    { key: "Alpha", color: "purple" },
    { key: "Beta", parent: "Alpha", color: "red" },
    { key: "Gamma", parent: "Alpha", color: "white" },
  ]);
}
</script>
<pre class="lang-js" style="display:none" id="diagramPre"><code>
  setupForLegend(diagram);
</code></pre>
<div style="width:100%">
  <span id="diagramSpan" style="display: inline-block">
    <span style="font: bold 16pt sans-serif; color:green">An HTML Title for a Diagram</span>
  </span>
  <div style="display: inline-block; vertical-align: bottom; border: 2px solid green">
    <b>Color key:</b>
    <table>
      <tr><td><span style="color:purple; font-weight:bold">Purple</span> nodes are juicy and sweet</td></tr>
      <tr><td><span style="color:red; font-weight:bold">Red</span> nodes are very angry</td></tr>
      <tr><td><span style="color:white;background:gray;font-weight:bold">White</span> nodes sleep well at night</td></tr>
    </table>
  </div>
</div>
<script>goCode("diagramPre", 300, 200, "diagramSpan");</script>
<p>
Note that anything in HTML will not automatically scroll and zoom along with the diagram's contents shown in the viewport.
But HTML elements could be positioned in front of or behind the diagram's DIV element.
</p>

<h2 id="UnmodeledParts">Unmodeled Parts</h2>
<p>
Second, you should consider whether the title or legend should be held in your data model.
Do you need to save and load that data in your database?
</p>
<p>
If you do not want to these objects to be included in your application's data model,
you can just create them as simple <a>Part</a>s and <a>Diagram.add</a> them to your diagram
at explicitly defined <a>Part.location</a>s.
</p>
<pre class="lang-js" id="unmodeled"><code>
  setupForLegend(diagram);  // this creates a diagram just like the first example

  diagram.add(
    $(go.Part, { location: new go.Point(0, -40) },
      $(go.TextBlock, "A Title", { font: "bold 24pt sans-serif", stroke: "green" })));
</code></pre>
<script>goCode("unmodeled", 300, 200);</script>
<p>
If you do not assign a location or position for your Parts,
and if your <a>Diagram.layout</a> (if any) does not assign any <a>Part.location</a>,
then there might not be a real location for those parts and they might not appear anywhere in the diagram.
</p>
<p class="box bg-info">
All of the predefined <a>Layout</a>s that make use of <a>LayoutNetwork</a>s, including <a>TreeLayout</a>,
do not operate on simple <a>Part</a>s but only on <a>Node</a>s and <a>Link</a>s.
If you had added a <a>Node</a> to the diagram it would have been positioned as part of this diagram's normal tree layout,
even though you explicitly set its location.
Alternatively it could still be a Node if you set its <a>Part.isLayoutPositioned</a> property to false.
</p>
<p>
You will notice that the title is selectable and movable and copyable and deletable in the diagram above.
You may want to set properties such as <a>Part.selectable</a> to false.
</p>
<p>
For an example showing a legend, see the <a href="../samples/familyTree.html" target="samples">Family Tree</a> sample.
</p>

<h3 id="ModeledParts">Modeled Parts</h3>
<p>
If on the other hand you do want to store your titles or legends in your model, you can do so using the normal mechanisms.
Typically you will use <a href="templateMaps.html">node categories and template maps</a>.
</p>
<p>
If you do not want your users to manipulate those objects, you will want to set <a>Part.selectable</a> to false.
You may want to set <a>Part.layerName</a> to "Grid", so that it is always in the background behind everything else.
(All Parts in the "Grid" Layer are automatically not selectable, because <a>Layer.allowSelect</a> is false for that <a>Layer</a>.)
</p>

<h2 id="StaticParts">Static Parts</h2>
<p>
Third, consider whether you want the title or legend to move or scale as the user scrolls or zooms the diagram.
If you want to keep such a decoration at the same position in the viewport, it might be easiest to do so by implementing
it as an HTML element that is superimposed with the diagram's DIV element.
</p>
<p>
However if you really want to implement it using a <b>GoJS</b> <a>Part</a>, you can do so by implementing a
"ViewportBoundsChanged" <a>DiagramEvent</a> listener that continually resets the position and scale to values that
make them appear not to move as the user scrolls or zooms.
</p>
<pre class="lang-js" id="static"><code>
  setupForLegend(diagram);  // this creates a diagram just like the first example

  diagram.add(
    $(go.Part,
      {
        layerName: "Grid",  // this Layer is behind everything and is not interactive
        _viewPosition: new go.Point(0,0)  // some position in the viewport,
                                          // not in document coordinates
      },
      $(go.TextBlock, "A Title", { font: "bold 24pt sans-serif", stroke: "green" })));

  // Whenever the Diagram.position or Diagram.scale change,
  // update the position of all simple Parts that have a _viewPosition property.
  diagram.addDiagramListener("ViewportBoundsChanged", function(e) {
    e.diagram.commit(function(dia) {
      // only iterates through simple Parts in the diagram, not Nodes or Links
      dia.parts.each(function(part) {
        // and only on those that have the "_viewPosition" property set to a Point
        if (part._viewPosition) {
          part.position = dia.transformViewToDoc(part._viewPosition);
          part.scale = 1/dia.scale;  // counteract any zooming
        }
      })
    }, null);  // set skipsUndoManager to true, to avoid recording these changes
  });
</code></pre>
<script>goCode("static", 300, 200);</script>
<p>
Note that as the user pans or scrolls or zooms the diagram, the title remains at the same viewport position
at apparently the same effective size.
This example makes use of the "Grid" <a>Layer</a> (see <a href="layers.html">Intro to Layers</a>), which
is convenient for making sure the title (or legend) stays in the background and does not participate in
selection or mouse events or the <a>UndoManager</a>.
</p>

      </div>
    </div>
  
  <div class="bg-nwoods-primary">
    <section class="max-w-screen-lg text-white container mx-auto py-2 px-12">
      <p id="version" class="leading-none mb-2 my-4">GoJS</p>
    </section>
  </div><footer class="bg-nwoods-primary text-white">
  <div class="container max-w-screen-lg mx-auto  px-8">
    <div class="w-full py-6">

        <div class="max-w-screen-lg xl:max-w-screen-xl mx-auto px-4 sm:px-6 md:px-8">
          <ul class="text-sm font-medium pb-14 sm:pb-20 grid grid-cols-1 sm:grid-cols-3 gap-y-10">
            <li class="list-none row-span-2">
              <h2 class="text-base font-semibold tracking-wide">GoJS</h2>
              <ul class="list-none space-y-4 md:space-y-1 px-0">
                <li>
                  <a href="../samples/index.html">Samples</a>
                </li>
                <li>
                  <a href="../learn/index.html">Learn</a>
                </li>
                <li>
                  <a href="../intro/index.html">Intro</a>
                </li>
                <li>
                  <a href="../api/index.html">API</a>
                </li>
                <li>
                  <a href="../changelog.html">Changelog</a>
                </li>
                <li>
                  <a href="https://github.com/NorthwoodsSoftware/GoJS">GitHub</a>
                </li>
              </ul>
            </li>
            <li class="list-none row-span-2">
              <h2 class="text-base font-semibold tracking-wide">Support</h2>
              <ul class="list-none space-y-4 md:space-y-1 px-0">
                <li>
                  <a href="https://www.nwoods.com/contact.html"
                  target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a>
                </li>
                <li>
                  <a href="https://forum.nwoods.com/c/gojs">Forum</a>
                </li>
                <li>
                  <a href="https://www.nwoods.com/app/activate.aspx?sku=gojs">Activate</a>
                </li>
                <li>
                  <a href="https://www.nwoods.com/sales/index.html"
                  target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a>
                </li>
                <li>
                  <a href="https://www.youtube.com/channel/UC9We8EoX596-6XFjJDtZIDg">Videos</a>
                </li>
              </ul>
            </li>
            <li class="list-none row-span-2">
              <h2 class="text-base font-semibold tracking-wide">Company</h2>
              <ul class="list-none space-y-4 md:space-y-1 px-0">
                <li>
                  <a href="https://www.nwoods.com">Northwoods</a>
                </li>
                <li>
                  <a href="https://www.nwoods.com/about.html">About Us</a>
                </li>
                <li>
                  <a href="https://www.nwoods.com/contact.html">Contact Us</a>
                </li>
                <li>
                  <a href="https://twitter.com/northwoodsgo">Twitter</a>
                </li>

              </ul>
            </li>
          </ul>


      <p class="text-sm text-gray-100 md:mb-6">
        Copyright 1998-2021 <a class="text-white" href="https://www.nwoods.com">Northwoods Software</a>
      </p>
    </div>
  </div>
</footer>  </body>

<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1506307-5"></script> 
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date()); gtag('config', 'UA-1506307-5');
  var getOutboundLink = function(url, label) {
    gtag('event', 'click', {
      'event_category': 'outbound',
      'event_label': label,
      'transport_type': 'beacon'
    });
  }

  // topnav
  var topButton = document.getElementById("topnavButton");
  var topnavList = document.getElementById("topnavList");
  topButton.addEventListener("click", function() {
    this.classList.toggle("active");
    topnavList.classList.toggle("hidden");
    document.getElementById("topnavOpen").classList.toggle("hidden");
    document.getElementById("topnavClosed").classList.toggle("hidden");
  });
</script>
  <script src="../assets/js/prism.js"></script>
  <script src="../release/go.js"></script>
  <script src="../assets/js/goDoc.js"></script>
  <script>
    document.addEventListener("DOMContentLoaded", function() {
      if (window.go) document.getElementById('version').textContent = "GoJS version " + go.version;
      if (window.goDoc) window.goDoc();
      var d = window.diagrams;
      for (var i = 0; i < d.length; i++) {
        var dargs = d[i];
        goCodeExecute(dargs[0], dargs[1], dargs[2], dargs[3], dargs[4]);
      }
      if (window.extra) window.extra();
    });
  </script>
</html>
